This section shows the Pascal data structures for the PixMap , CGrafPort , RGBColor , ColorSpec , ColorTable , MatchRec , PixPat , CQDProcs , and GrafVars records.
Analogous to the bitmap that basic QuickDraw uses to describe a bit image, a pixel map is used by Color QuickDraw to describe a pixel image. A pixel map, which is a data structure of type PixMap , contains information about the dimensions and contents of a pixel image, as well as information about the image's storage format, depth, resolution, and color usage.
As a basic graphics port (described in the chapter "Basic QuickDraw") defines the black-and-white and basic eight-color drawing environment for basic QuickDraw, a color graphics port defines the more sophisticated color drawing environment for Color QuickDraw. A color graphics port is defined by a data structure of type CGrafPort .
You usually specify a color to Color QuickDraw by creating an RGBColor record in which you assign the red, green, and blue values of the color. For example, when you want to set the foreground color for drawing, you create an RGBColor record that defines the foreground color you desire, then you pass that record as a parameter to the RGBForeColor procedure.
When creating a PixMap record for an indexed device, Color QuickDraw creates a ColorTable record that defines the best colors available for the pixel image on that graphics device. The Color Manager also stores a ColorTable record for the currently available colors in the graphics device's CLUT.
One of the fields in a ColorTable record requires a value of type cSpecArray , which is defined as an array of ColorSpec records. Typically, your application needs to create ColorTable records and ColorSpec records only if it uses the Palette Manager, as described in the chapter "Palette Manager" in Inside Macintosh: Advanced Color Imaging .
You can customize the SeedCFill and CalcCMask procedures by writing your own color search functions and pointing to them in the matchProc parameters for these procedures. When SeedCFill or CalcCMask calls your color search function, the GDRefCon field of the current GDevice record (described in the chapter "Graphics Devices") contains a pointer to a MatchRec record. This record contains the RGB value of the seed pixel or seed color for which your color search function should search.
Your application typically does not create PixPat records. Although you can create PixPat records in your program code, it is usually easier to create pixel patterns using the pixel pattern resource, which is described on The Pixel Pattern Resource .
You need to use the CQDProcs record only if you customize one or more of QuickDraw's low-level drawing routines.
Finally, the GrafVars record contains color information that supplements the information in the CGrafPort record, of which it is logically a part.
A pixel map, which is defined by a data structure of type PixMap , contains information about the dimensions and contents of a pixel image, as well as information on the image's storage format, depth, resolution, and color usage.
TYPE PixMap =
RECORD
baseAddr: Ptr; {pixel image}
rowBytes: Integer; {flags, and row width}
bounds: Rect; {boundary rectangle}
pmVersion: Integer; {PixMap record version number}
packType: Integer; {packing format}
packSize: LongInt; {size of data in packed state}
hRes: Fixed; {horizontal resolution}
vRes: Fixed; {vertical resolution}
pixelType: Integer; {format of pixel image}
pixelSize: Integer; {physical bits per pixel}
cmpCount: Integer; {logical components per pixel}
cmpSize: Integer; {logical bits per component}
planeBytes: LongInt; {offset to next plane}
pmTable: CTabHandle; {handle to the ColorTable record }
{ for this image}
pmReserved: LongInt; {reserved for future expansion}
END;
The baseAddr field of the PixMap record for an offscreen graphics world contains a handle instead of a pointer. You must use the GetPixBaseAddr function (described in the chapter "Offscreen Graphics Worlds" in this book) to obtain a pointer to the PixMap record for an offscreen graphics world. Your application should never directly access the baseAddr field of the PixMap record for an offscreen graphics world; instead, your application should always use GetPixBaseAddr .
Note that the pixel map for a window's color graphics port always consists of the pixel depth, color table, and boundary rectangle of the main screen, even if the window is created on or moved to an entirely different screen.
A color graphics port, which is defined by a data structure of type CGrafPort , defines a complete drawing environment that determines where and how color graphics operations take place.
All graphics operations are performed in graphics ports. Before a color graphics port can be used, it must be allocated and initialized with the OpenCPort procedure, which is described on OpenCPort . Normally, you don't call OpenCPort yourself. In most cases your application draws into a color window you've created with the GetNewCWindow or NewCWindow function or draws into an offscreen graphics world created with the NewGWorld function. The two Window Manager functions (described in the chapter "Window Manager" in Inside Macintosh: Macintosh Toolbox Essentials ) and the NewGWorld function (described in the chapter "Offscreen Graphics Worlds" in this book) call OpenCPort to create the window's graphics port.
You can have many graphics ports open at once; each one has its own local coordinate system, pen pattern, background pattern, pen size and location, font and font style, and pixel map in which drawing takes place.
Several fields in this record define your application's drawing area. All drawing in a graphics port occurs in the intersection of the graphics port's boundary rectangle and its port rectangle. Within that intersection, all drawing is cropped to the graphics port's visible region and its clipping region.
The Window Manager and Dialog Manager routines GetNewWindow , GetNewDialog , Alert , StopAlert , NoteAlert , and CautionAlert (described in Inside Macintosh: Macintosh Toolbox Essentials ) create a color graphics port if color-aware resources (such as resource types 'wctb' , 'dctb' , or 'actb' ) are present.
The CGrafPort record is the same size as the GrafPort record, and most of its fields are identical. The structure of the CGrafPort record, is as follows:
TYPE CGrafPtr=^CGrafPort;
CGrafPort =
RECORD
device: Integer; {device ID for font selection}
portPixMap: PixMapHandle; {handle to PixMap record}
portVersion: Integer; {highest 2 bits always set}
grafVars: Handle; {handle to a GrafVars record}
chExtra: Integer; {added width for nonspace characters}
pnLocHFrac: Integer; {pen fraction}
portRect: Rect; {port rectangle}
visRgn: RgnHandle; {visible region}
clipRgn: RgnHandle; {clipping region}
bkPixPat: PixPatHandle; {background pattern}
rgbFgColor: RGBColor; {requested foreground color}
rgbBkColor: RGBColor; {requested background color}
pnLoc: Point; {pen location}
pnSize: Point; {pen size}
pnMode: Integer; {pattern mode}
pnPixPat: PixPatHandle; {pen pattern}
fillPixPat: PixPatHandle; {fill pattern}
pnVis: Integer; {pen visibility}
txFont: Integer; {font number for text}
txFace: Style; {text's font style}
txMode: Integer; {source mode for text}
txSize: Integer; {font size for text}
spExtra: Fixed; {added width for space characters}
fgColor: LongInt; {actual foreground color}
bkColor: LongInt; {actual background color}
colrBit: Integer; {plane being drawn}
patStretch: Integer; {used internally}
picSave: Handle; {picture being saved, used internally}
rgnSave: Handle; {region being saved, used internally}
polySave: Handle; {polygon being saved, used internally}
grafProcs: CQDProcsPtr; {low-level drawing routines}
END;
You can read the fields of a CGrafPort record directly, but you should not store values directly into them. Use the QuickDraw routines described in this book to alter the fields of a graphics port.
All Color QuickDraw operations refer to a graphics port by a pointer defined by the data type CGrafPtr . (For historical reasons, a graphics port is one of the few objects in the Macintosh system software that's referred to by a pointer rather than a handle.) All Window Manager routines that accept a window pointer also accept a pointer to a color graphics port.
Your application should never need to directly change the fields of a CGrafPort record. If you find it absolutely necessary for your application to so, immediately use the PortChanged procedure to notify Color QuickDraw that your application has changed the CGrafPort record. The PortChanged procedure is described on PortChanged .
You usually specify a color to Color QuickDraw by creating an RGBColor record in which you assign the red, green, and blue values of the color. For example, when you want to set the foreground color for drawing, you create an RGBColor record that defines the foreground color you desire; then you pass that record as a parameter to the RGBForeColor procedure.
In an RGBColor record, three 16-bit unsigned integers give the intensity values for the three additive primary colors.
TYPE RGBColor=
RECORD
red: Integer; {redcomponent}
green: Integer; {greencomponent}
blue: Integer; {bluecomponent}
END;
When creating a PixMap record (described on PixMap ) for an indexed device, Color QuickDraw creates a ColorTable record that defines the best colors available for the pixel image on that graphics device. The Color Manager also stores a ColorTable record for the currently available colors in the graphics device's CLUT.
One of the fields in a ColorTable record requires a value of type cSpecArray , which is defined as an array of ColorSpec records. Typically, your application never needs to create ColorTable records or ColorSpec records. For completeness, the data structure of type ColorSpec is shown here, and the data structure of type ColorTable is shown next.
TYPE
cSpecArray: ARRAY[0..0] Of ColorSpec;
ColorSpec =
RECORD
value: Integer; {index or other value}
rgb: RGBColor; {true color}
END;
When creating a PixMap record (described on PixMap ) for a particular graphics device, Color QuickDraw creates a ColorTable record that defines the best colors available for the pixel image on that particular graphics device. The Color Manager also creates a ColorTable record of all available colors for use by the CLUT on indexed devices.
Typically, your application needs to create ColorTable records only if it uses the Palette Manager, as described in the chapter "Palette Manager" in Inside Macintosh: Advanced Color Imaging. The data structure of type ColorTable is shown here.
TYPE CTabHandle =^CTabPtr;
CTabPtr =^ColorTable;
ColorTable =
RECORD
ctSeed: LongInt; {unique identifier from table}
ctFlags: Integer; {flags describing the value in the }
{ ctTable field; clear for a pixel map}
ctSize: Integer; {numberofentriesinthe next field }
{ minus 1}
ctTable: cSpecArray; {an array of ColorSpec records}
END;
Your application should never need to directly change the fields of a ColorTable record. If you find it absolutely necessary for your application to so, immediately use the CTabChanged procedure to notify Color QuickDraw that your application has changed the ColorTable record. The CTabChanged procedure is described on CTabChanged .
As described in "Application-Defined Routine" , you can customize the SeedCFill and CalcCMask procedures by writing your own color search functions and pointing to them in the matchProc parameters for these procedures.
When SeedCFill or CalcCMask calls your color search function, the GDRefCon field of the current GDevice record (described in the chapter "Graphics Devices") contains a pointer to a MatchRec record. This record contains the RGB value of the seed pixel or seed color for which your color search function should search. This record has the following structure:
MatchRec =
RECORD
red: Integer; {red component of seed}
green: Integer; {green component of seed}
blue: Integer; {blue component of seed}
matchData: LongInt; {value in matchData parameter of }
{ SeedCFill or CalcCMask}
END;
Your application typically does not create PixPat records. Although you can create such records in your program code, it is usually easier to create pixel patterns using the pixel pattern resource, which is described on The Pixel Pattern Resource .
A PixPat record is defined as follows:
TYPE PixPatHandle = ^PixPatPtr;
PixPatPtr = ^PixPat;
PixPat =
RECORD
patType : Integer; {pattern type}
patMap: PixMapHandle; {pattern characteristics}
patData: Handle; {pixel image defining pattern}
patXData: Handle; {expanded pixel image}
patXValid: Integer; {flags for expanded pattern data}
patXMap: Handle; {handle to expanded pattern data}
pat1Data: Pattern; {a bit pattern for a GrafPort }
{ record}
END;
When used for a color graphics port, the basic QuickDraw procedures PenPat and BackPat (described in the chapter "Basic QuickDraw") store pixel patterns in, respectively, the pnPixPat and bkPixPat fields of the CGrafPort record and set the patType field of the PixPat field to 0 to indicate that the PixPat record contains a bit pattern. Such patterns are limited to 8-by-8 pixel dimensions and, instead of being drawn in black and white, are always drawn using the colors specified in the CGrafPort record's rgbFgColor and rgbBkColor fields, respectively.
In a full-color pixel pattern, the patType field contains the value 1, and the pattern's dimensions, depth, resolution, set of colors, and other characteristics are defined by a PixMap record, referenced by the handle in the patMap field of the PixPat record. Full-color pixel patterns contain color tables that describe the colors they use. Generally such a color table contains one entry for each color used in the pattern. For instance, if your pattern has five colors, you would probably create a 4 bits per pixel pattern that uses pixel values 0-4, and a color table with five entries, numbered 0-4, that contain the RGB specifications for those pixel values.
However, if you don't specify a color table for a pixel value, Color QuickDraw assigns a color to that pixel value. The largest unassigned pixel value becomes the foreground color; the smallest unassigned pixel value is assigned the background color. Remaining unassigned pixel values are given colors that are evenly distributed between the foreground and background.
For instance, in the color table mentioned above, pixel values 5-15 are unused. Assume that the foreground color is black and the background color is white. Pixel value 15 is assigned the foreground color, black; pixel value 5 is assigned the background color, white; the nine pixel values between them are assigned evenly distributed shades of gray. If the PixMap record's color table is set to NIL , all pixel values are determined by blending the foreground and background colors.
Full-color pixel patterns are not limited to a fixed size: their height and width can be any power of 2, as specified by the height and width of the boundary rectangle for the PixMap record specified in the patMap field. A pattern 8 bits wide, which is the size of a bit pattern, has a row width of just 1 byte, contrary to the usual rule that the rowBytes field must be even. Read this pattern type into memory using the GetPixPat function (described on GetPixPat ), and set it using the PenPixPat or BackPixPat procedure (described on PenPixPat and BackPixPat , respectively).
The pixel map specified in the patMap field of the PixPat record defines the pattern's characteristics. The baseAddr field of the PixMap record for that pixel map is ignored. For a full-color pixel pattern, the actual pixel image defining the pattern is stored in the handle in the patData field of the PixPat record. The pattern's pixel depth need not match that of the pixel map into which it's transferred; the depth is adjusted automatically when the pattern is drawn. Color QuickDraw maintains a private copy of the pattern's pixel image, expanded to the current screen depth and aligned to the current graphics port, in the patXData field of the PixPat record.
In an RGB pixel pattern, the patType field contains the value 2. Using the MakeRGBPat procedure (described on MakeRGBPat ), your application can specify the exact color it wants to use. Color QuickDraw selects a pattern to approximate that color. In this way, your application can effectively increase the color resolution of the screen. RGB pixel patterns are particularly useful for dithering: mixing existing colors together to create the illusion of a third color that's unavailable on an indexed device. The MakeRGBPat procedure aids in this process by constructing a dithered pattern to approximate a given absolute color. An RGB pixel pattern can display 125 different patterns on a 4-bit screen, or 2197 different patterns on an 8-bit screen.
An RGB pixel pattern has an 8-by-8 pixel pattern that is 2 bits deep. For an RGB pixel pattern, the RGBColor record that you specify to the MakeRGBPat procedure defines the image; there is no image data.
Your application should never need to directly change the fields of a PixPat record. If you find it absolutely necessary for your application to so, immediately use the PixPatChanged procedure to notify Color QuickDraw that your application has changed the PixPat record. The PixPatChanged procedure is described on PixPatChanged .
You need to use the CQDProcs record only if you customize one or more of QuickDraw's standard low-level drawing routines, which are described in the chapter "QuickDraw Drawing." You can use the SetStdCProcs procedure, described on SetStdCProcs , to create a CQDProcs record.
CQDProcsPtr = ^CQDProcs
CQDProcs =
RECORD
textProc: Ptr; {text drawing}
lineProc: Ptr; {line drawing}
rectProc: Ptr; {rectangle drawing}
rRectProc: Ptr; {roundRect drawing}
ovalProc: Ptr; {oval drawing}
arcProc: Ptr; {arc/wedge drawing}
polyProc: Ptr; {polygon drawing}
rgnProc: Ptr; {region drawing}
bitsProc: Ptr; {bit transfer}
commentProc: Ptr; {picture comment processing}
txMeasProc: Ptr; {text width measurement}
getPicProc: Ptr; {picture retrieval}
putPicProc: Ptr ; {picture saving}
opcodeProc: Ptr; {reserved for future use}
newProc1: Ptr; {reserved for future use}
newProc2: Ptr; {reserved for future use}
newProc3: Ptr; {reserved for future use}
newProc4: Ptr; {reserved for future use}
newProc5: Ptr; {reserved for future use}
newProc6: Ptr; {reserved for future use}
END;
The GrafVars record contains color information in addition to that in the CGrafPort record, of which it is logically a part; the information is used by Color QuickDraw and the Palette Manager.
TYPE GrafVars =
RECORD
rgbOpColor: RGBColor; {color for addPin, subPin, and }
{ blend}
rgbHiliteColor: RGBColor; {color for highlighting}
pmFgColor: Handle; {palette handle for foreground }
{ color}
pmFgIndex: Integer; {index value for foreground}
pmBkColor: Handle; {palette handle for background }
{ color}
pmBkIndex: Integer; {index value for background}
pmFlags: Integer; {flags for Palette Manager}
END;
See the chapter "Palette Manager" in Inside Macintosh: Advanced Color Imaging for further information on how the Palette Manager handles colors in a color graphics port.